from rest_framework import serializers
from system import models
from django.db.models import F


class MenuModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Menu
        fields = ['component', 'pid', 'id', 'hidden', 'meta', 'name', 'path']

    id = serializers.IntegerField()
    pid = serializers.PrimaryKeyRelatedField(read_only=True)
    meta = serializers.SerializerMethodField(read_only=True)

    def get_meta(self, obj):
        return {
            'icon': obj.icon,
            'noCache': True,
            'title': obj.title
        }


class MenuSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Menu
        fields = ['cache', 'component', 'componentName', 'createTime', 'hasChildren',
                  'hidden', 'iFrame', 'icon', 'id', 'label', 'leaf', 'menuSort',
                  'path', 'permission', 'pid', 'subCount', 'title', 'type']

    subCount = serializers.SerializerMethodField()

    def get_subCount(self, obj):
        return obj.sub_count

    componentName = serializers.SerializerMethodField()

    def get_componentName(self, obj):
        return obj.name

    createTime = serializers.SerializerMethodField()

    def get_createTime(self, obj):
        return obj.create_time

    hasChildren = serializers.SerializerMethodField()

    def get_hasChildren(self, obj):
        if obj.sub_count:
            return True
        else:
            return False

    iFrame = serializers.SerializerMethodField()

    def get_iFrame(self, obj):
        return obj.i_frame

    label = serializers.SerializerMethodField()

    def get_label(self, obj):
        return obj.title

    leaf = serializers.SerializerMethodField()

    def get_leaf(self, obj):
        if obj.is_menu:
            return False
        else:
            return True

    menuSort = serializers.SerializerMethodField()

    def get_menuSort(self, obj):
        return obj.menu_sort


class CreateMenuSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Menu
        fields = ['cache', 'component', 'componentName', 'createTime', 'hasChildren', 'hidden',
                  'iFrame', 'icon', 'id', 'iframe', 'label', 'leaf', 'menuSort', 'path', 'permission',
                  'pid', 'roles', 'subCount', 'title', 'type']

    componentName = serializers.CharField(read_only=True)
    createTime = serializers.CharField(read_only=True)
    hasChildren = serializers.CharField(read_only=True)
    iFrame = serializers.CharField(read_only=True)
    iframe = serializers.CharField(read_only=True)
    label = serializers.CharField(read_only=True)
    leaf = serializers.CharField(read_only=True)
    menuSort = serializers.CharField(read_only=True)
    roles = serializers.CharField(read_only=True)
    subCount = serializers.CharField(read_only=True)
    pid = serializers.CharField(read_only=True)

    def validate(self, attrs):
        request = self.context.get('request')
        attrs['create_by'] = request.user.username
        attrs['sub_count'] = 0
        attrs['menu_sort'] = request.data.get('menuSort')
        return attrs

    def create(self, validated_data):
        """
        1. 判断是否是顶级目录
            1. 顶级目录直接create, sub_count = 0
        2. 不是顶级目录
            1. create
            2. 给新增的父级目录的sub_count + 1
        :param validated_data:
        :return:
        """
        request = self.context.get('request')
        if request.data.get('path'):  # 菜单和目录
            if request.data.get('pid') == 0:
                validated_data['is_menu'] = True
                menu = models.Menu.objects.create(**validated_data)
                return menu
            else:
                parent_id = request.data.get('pid')  # 父菜单id
                validated_data['pid_id'] = parent_id
                validated_data['is_menu'] = True
                validated_data['name'] = request.data.get('componentName')
                models.Menu.objects.filter(pk=parent_id).update(sub_count=F('sub_count') + 1)
                menu = models.Menu.objects.create(**validated_data)
                return menu
        else:  # 按钮
            parent_id = request.data.get('pid')  # 父菜单id
            validated_data['pid_id'] = parent_id
            validated_data['name'] = request.data.get('componentName')
            models.Menu.objects.filter(pk=parent_id).update(sub_count=F('sub_count') + 1)
            menu = models.Menu.objects.create(**validated_data)
            return menu


class UpdateMenuSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Menu
        fields = ['cache', 'component', 'hidden', 'icon', 'id', 'path', 'permission',
                  'pid', 'title', 'type']

    pid = serializers.CharField(read_only=True)

    def validate(self, attrs):
        request = self.context.get('request')
        attrs['update_by'] = request.user.username
        return attrs

    def update(self, instance, validated_data):
        """
        1. 原父菜单sub_count - 1   顶级菜单的修改不难减一
            如果拿到当前菜单的父菜单id为0,,那就只加他的现在的夫菜单的sub_count
        2. 现父菜单 sub_count + 1
        :param instance:
        :param validated_data:
        :return:
        """
        request = self.context.get('request')
        id = request.data.get('id')  # 当前修改的菜单id
        new_parent_id =request.data.get('pid') if request.data.get('pid') else None # 修改后菜单的父菜单
        old_parent_id = instance.pid_id if instance.pid_id else None                # 修改前的父菜单
        if old_parent_id:  # 当前修改的菜单是一个子菜单
            print(validated_data)
            validated_data['pid_id'] = request.data.get('pid')
            models.Menu.objects.filter(pk=old_parent_id).update(sub_count=F('sub_count') - 1)
            models.Menu.objects.filter(pk=new_parent_id).update(sub_count=F('sub_count') + 1)
            return super().update(instance, validated_data)
        else:            # 修改对象是一个顶级菜单
            print(validated_data)
            if new_parent_id:
                models.Menu.objects.filter(pk=new_parent_id).update(sub_count=F('sub_count') + 1)
            return super().update(instance, validated_data)




